#!/usr/bin/env pyahont3

"""
练习作业：01
1. 贪吃蛇游戏
参考游戏：http://www.4399.com/flash/76879_2.htm


#coding=utf-8
# Write By Guobao
# 2017/4//7
#
# 贪吃蛇
# 用#做边界，*做食物，o做身体和头部
# python 3.6.1   
import copy
import random
import os
import msvcrt
# the board class, used to put everything
class board:

    __points =[]

    def __init__(self):
        self.__points.clear()
        for i in range(22):
            line = []
            if i == 0 or i == 21:
                for j in range(22):
                    line.append('#')
            else:
                line.append('#')
                for j in range(20):
                    line.append(' ')
                line.append('#')
            self.__points.append(line)

    def getPoint(self, location):
        return self.__points[location[0]][location[1]]

    def clear(self):
        self.__points.clear()
        for i in range(22):
            line = []
            if i == 0 or i == 21:
                for j in range(22):
                    line.append('#')
            else:
                line.append('#')
                for j in range(20):
                    line.append(' ')#!
                line.append('#')
            self.__points.append(line)

    def put_snake(self, snake_locations):
        # clear the board
        self.clear()

        # put the snake points
        for x in snake_locations:
            self.__points[x[0]][x[1]] = 'o'

        # the head
        x = snake_locations[len(snake_locations) - 1]
        self.__points[x[0]][x[1]] = 'O'

    def put_food(self, food_location):
        self.__points[food_location[0]][food_location[1]] = '*'

    def show(self):
        os.system("cls")
        for i in range(22):
            for j in range(22):
                print(self.__points[i][j], end='')
            print()

# the snake class
class snake:
    __points = []

    def __init__(self):
        for i in range(1, 6):
            self.__points.append([1, i])

    def getPoints(self):
        return self.__points

    # move to the next position
    # give the next head
    def move(self, next_head):
        self.__points.pop(0)
        self.__points.append(next_head)

    # eat the food
    # give the next head
    def eat(self, next_head):
        self.__points.append(next_head)

    # calc the next state
    # and return the direction
    def next_head(self, direction='default'):

        # need to change the value, so copy it
        head = copy.deepcopy(self.__points[len(self.__points) - 1])

        # calc the "default" direction
        if direction == 'default':
            neck = self.__points[len(self.__points) - 2]
            if neck[0] > head[0]:
                direction = 'up'
            elif neck[0] < head[0]:
                direction = 'down'
            elif neck[1] > head[1]:
                direction = 'left'
            elif neck[1] < head[1]:
                direction = 'right'

        if direction == 'up':
            head[0] = head[0] - 1
        elif direction == 'down':
            head[0] = head[0] + 1
        elif direction == 'left':
            head[1] = head[1] - 1
        elif direction == 'right':
            head[1] = head[1] + 1
        return head

# the game
class game:

    board = board()
    snake = snake()
    food = []
    count = 0

    def __init__(self):
        self.new_food()
        self.board.clear()
        self.board.put_snake(self.snake.getPoints())
        self.board.put_food(self.food)

    def new_food(self):
        while 1:
            line=random.randint(2,19)
            column=random.randint(2,19)
            if self.board.getPoint([column, line]) == ' ':
                self.food = [column, line]
                return

    def show(self):
        self.board.clear()
        self.board.put_snake(self.snake.getPoints())
        self.board.put_food(self.food)
        self.board.show()


    def run(self):
        self.board.show()

        # the 'w a s d' are the directions
        operation_dict = {b'w': 'up', b'up': 'up', b's': 'down', b'S': 'down', b'a': 'left', b'A': 'left', b'd': 'right', b'D': 'right'}
        op = msvcrt.getch()

        while op != b'q':
            if op not in operation_dict:
                op = msvcrt.getch()
            else:
                new_head = self.snake.next_head(operation_dict[op])

                # get the food
                if self.board.getPoint(new_head) == '*':
                    self.snake.eat(new_head)
                    self.count = self.count + 1
                    if self.count >= 20:#!
                        self.show()
                        print("Good Job")
                        break
                    else:
                        self.new_food()
                        self.show()

                # 反向一Q日神仙
                elif new_head == self.snake.getPoints()[len(self.snake.getPoints()) - 2]:
                    pass

                # rush the wall
                elif self.board.getPoint(new_head) == '#' or self.board.getPoint(new_head) == 'o':
                    print("GG")
                    break 
                    

                # normal move
                else:
                    self.snake.move(new_head)
                    self.show()
            op = msvcrt.getch()

game().run()
"""
import pygame
import random
pygame.init()

#Window setup
size = [400, 300]
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()

#player position
x = size[0] / 2
y = size[1] / 2

#ball position
ballX = random.randrange(0, size[0])
ballY = random.randrange(0, size[1])

#goal position
goalX = size[0]/2 - 10
goalY = size[1]/2 - 10
goalW = 20
goalH = 20

#pointes
points = 100
point = 0
pointX = 0
f=0
#colors
red = pygame.color.Color('#FF8080')
blue = pygame.color.Color('#8080FF')
white = pygame.color.Color('#FFFFFF')
black = pygame.color.Color('#000000')

def CheckOffScreenX(x):
    if x > size[0]:
        x = 0
    elif x < 0:
        x = size[0]
    return x

def CheckOffScreenY(y):
    if y > size[1]:
        y = 0
    elif y < 0:
        y = size[1]
    return y

def checkTouching():
    #"""Causes a small explosion if the players are touching"""
    global x
    global ballX
    global y
    global ballY

    #check if player and ball are touching
    if -10 < y - ballY < 10 and -10 < x - ballX <10:
        #draw an explosion
        pygame.draw.circle(screen, white, [x, y], 15)

        xDiff = x - ballX
        yDiff = y - ballY

        #check if ball is on edge of screen
        if ballX == 0:
            xDiff -= 5
        elif ballX == size[0]:
            xDiff += 5
        if ballY == 0:
            yDiff -= 5
        elif ballY == size[1]:
            yDiff += 5

        #move the ball and player
        x += yDiff * 3
        ballX -= xDiff * 3

        y += yDiff * 3
        ballY -= yDiff * 3

#Game loop
done = False

#get current time
timeStart = pygame.time.get_ticks()

while not done:
    screen.fill(black)

    #Draw the goal
    pygame.draw.rect(screen, white, (goalX, goalY, goalW, goalH))

    #check ball is in goal
    if goalX <= ballX <= goalX + goalH and goalY <= ballY <= goalY + goalH:
        points += 1
        f+=1
        ballX = random.randrange(0, size[0])
        ballY = random.randrange(0, size[1]) 

    #draw points 
    for point in range(points):
        pointX = 0 + point*5
    pygame.draw.rect(screen, white, (pointX, 3, 4, 7))

    keys = pygame.key.get_pressed()

    #player movement
    if keys[pygame.K_w]:
        y -= 1

    if keys[pygame.K_s]:
        y += 1

    if keys[pygame.K_a]:
        x -= 1

    if keys[pygame.K_d]:
        x += 1

    #check off screen
    x = CheckOffScreenX(x)
    y = CheckOffScreenY(y)
    ballX = CheckOffScreenX(ballX)
    ballY = CheckOffScreenY(ballY)

    #draw player
    pygame.draw.circle(screen, red, [x,y], 6)

    #check if player is touching the ball
    checkTouching()

    #draw ball
    pygame.draw.circle(screen, blue, [ballX, ballY], 6)

    pygame.display.flip()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        clock.tick(72)

        #Check elapsed time
        timeNow = pygame.time.get_ticks()
        if timeNow - timeStart >= 6000000:
            done = True

pygame.quit()

#print on shell window
print ("Total Points:" + str(points))
print ("Remaining time:" + str(timeNow - timeStart))
print(f)